#include "http.hpp"

static const std::string WWWROOT = "./wwwroot/";

// 辅助函数：获取请求的详细信息（用于调试）
std::string RequestStr(const HttpRequest &req) {
    std::stringstream ss;
    ss << req._method << " " << req._path << " " << req._version << "\r\n";
    for (auto &it : req._params) {
        ss << "Param: " << it.first << "=" << it.second << "\r\n";
    }
    for (auto &it : req._headers) {
        ss << "Header: " << it.first << ": " << it.second << "\r\n";
    }
    ss << "\r\nBody:\r\n" << req._body;
    return ss.str();
}


// 1. 处理GET /hello
void Hello(const HttpRequest &req, HttpResponse *rsp) {
    // 返回HTML格式的欢迎页面（更友好）
    std::string html = R"(
        <html>
        <head><title>欢迎</title></head>
        <body>
            <h1 style="color: #2563eb;">Hello, World!</h1>
            <p>这是一个简单的HTTP服务器示例</p>
        </body>
        </html>
    )";
    rsp->SetContent(html, "text/html");
}

// 2. 处理POST /login
void Login(const HttpRequest &req, HttpResponse *rsp) {
    std::vector<std::string> form_data;
    Util::Split(req._body, "&", &form_data);
    std::unordered_map<std::string, std::string> form;
    for (auto &item : form_data) {
        size_t pos = item.find("=");
        if (pos != std::string::npos) {
            std::string key = Util::UrlDecode(item.substr(0, pos), true);
            std::string val = Util::UrlDecode(item.substr(pos + 1), true);
            form[key] = val;
        }
    }

    // 简单验证（实际项目需对接数据库）
    if (form["username"].empty() || form["password"].empty()) {
        rsp->_statu = 400; // 参数错误
        rsp->SetContent("用户名或密码不能为空", "text/plain");
        return;
    }

    // 登录成功响应
    rsp->SetContent("登录成功！用户名：" + form["username"], "text/plain");
}

// 3. 处理PUT /files/xxx（通用文件路径匹配）
// 正则：^/files/(.+)$ 匹配/files/下的所有文件（如/files/test.txt、/files/docs/readme.md）
void PutFile(const HttpRequest &req, HttpResponse *rsp) {
    // 从正则匹配中获取文件名（req._matches[2]对应捕获组(.+)）
    std::string filename = req._path; 
    std::string pathname = WWWROOT  + filename; // 统一存到wwwroot/files目录

    // 安全检查：防止目录穿越（如../etc/passwd）
    if (!Util::ValidPath("files/" + filename)) {
        rsp->_statu = 403; // 禁止访问
        rsp->SetContent("非法文件路径", "text/plain");
        return;
    }

    // 写入文件
    if (Util::WriteFile(pathname, req._body)) {
        rsp->_statu = 201; // 创建成功
        rsp->SetContent("文件创建成功：" + filename, "text/plain");
    } else {
        rsp->_statu = 500; // 服务器错误
        rsp->SetContent("文件创建失败", "text/plain");
    }
}

// 4. 处理DELETE /files/xxx（通用文件路径匹配）
// 正则：^/files/(.+)$ 与PUT保持一致，匹配/files/下的文件
void DelFile(const HttpRequest &req, HttpResponse *rsp) {
    std::string filename = req._path;
    std::string pathname = WWWROOT  + filename;

    // 安全检查
    if (!Util::ValidPath("files/" + filename)) {
        rsp->_statu = 403;
        rsp->SetContent("非法文件路径", "text/plain");
        return;
    }

    // 检查文件是否存在
    if (!Util::IsRegular(pathname)) {
        rsp->_statu = 404; // 文件不存在
        rsp->SetContent("文件不存在：" + filename, "text/plain");
        return;
    }

    // 删除文件
    if (remove(pathname.c_str()) == 0) {
        rsp->_statu = 204; // 无内容（删除成功）
        rsp->SetContent("", "text/plain"); // 204通常不带body
    } else {
        rsp->_statu = 500;
        rsp->SetContent("文件删除失败", "text/plain");
    }
}



int main()
{
    HttpServer server(8085);
    server.SetThreadCount(3);
    server.SetBaseDir(WWWROOT);//设置静态资源根目录，告诉服务器有静态资源请求到来，需要到哪里去找资源文件
    // 注册路由
    server.Get("^/hello$", Hello);         // 精确匹配/hello
    server.Post("^/login$", Login);        // 精确匹配/login
    server.Put("^/files/(.+)$", PutFile);  // 匹配/files/任意文件
    server.Delete("^/files/(.+)$", DelFile);// 匹配/files/任意文件
    server.Listen();
    return 0;
}